From 5d7ece5bae6289c5d837426ee883e1beaac414ae Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 30 Apr 2014 13:06:02 -0700 Subject: [PATCH] Cleanup + topological sort --- src/cargo/core/dependency.rs | 8 ++-- src/cargo/core/manifest.rs | 2 +- src/cargo/core/mod.rs | 8 +++- src/cargo/core/namever.rs | 40 ++++++++++++++++++++ src/cargo/core/package.rs | 41 ++------------------ src/cargo/core/source.rs | 2 +- src/cargo/mod.rs | 4 +- src/cargo/ops/cargo_compile.rs | 4 -- src/cargo/ops/cargo_read_manifest.rs | 3 +- src/cargo/ops/cargo_rustc.rs | 7 ++-- src/cargo/sources/path.rs | 2 +- src/cargo/util/graph.rs | 56 ++++++++++++++++++++++++++++ src/cargo/util/mod.rs | 1 + 13 files changed, 119 insertions(+), 59 deletions(-) create mode 100644 src/cargo/core/namever.rs create mode 100644 src/cargo/util/graph.rs diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs index 25a5f066e..6b1e11da9 100644 --- a/src/cargo/core/dependency.rs +++ b/src/cargo/core/dependency.rs @@ -1,17 +1,17 @@ -use core::package::NameVer; +use core; #[deriving(Eq,Clone,Show)] pub struct Dependency { - name: NameVer + name: core::NameVer } impl Dependency { pub fn new(name: &str) -> Dependency { - Dependency { name: NameVer::new(name.to_owned(), "1.0.0") } + Dependency { name: core::NameVer::new(name.to_owned(), "1.0.0") } } pub fn with_name_and_version(name: &str, version: &str) -> Dependency { - Dependency { name: NameVer::new(name, version) } + Dependency { name: core::NameVer::new(name, version) } } pub fn get_name<'a>(&'a self) -> &'a str { diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 6cca1442d..d4a4c6801 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -1,4 +1,4 @@ -use core::package::NameVer; +use core::NameVer; /* * TODO: Make all struct fields private diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index e152908a5..49ee02f38 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -1,3 +1,7 @@ +pub use self::namever::{ + NameVer +}; + pub use self::registry::{ Registry, MemRegistry @@ -11,12 +15,12 @@ pub use self::manifest::{ }; pub use self::package::{ - Package, - NameVer + Package }; pub use self::dependency::Dependency; +pub mod namever; pub mod source; pub mod package; pub mod dependency; diff --git a/src/cargo/core/namever.rs b/src/cargo/core/namever.rs new file mode 100644 index 000000000..48998627f --- /dev/null +++ b/src/cargo/core/namever.rs @@ -0,0 +1,40 @@ +use semver; +use serialize::{ + Encodable, + Encoder, + Decodable, + Decoder +}; + +#[deriving(Clone,Eq,Show,Ord)] +pub struct NameVer { + name: ~str, + version: semver::Version +} + +impl NameVer { + pub fn new(name: &str, version: &str) -> NameVer { + NameVer { name: name.to_owned(), version: semver::parse(version.to_owned()).unwrap() } + } + + pub fn get_name<'a>(&'a self) -> &'a str { + self.name.as_slice() + } + + pub fn get_version<'a>(&'a self) -> &'a semver::Version { + &self.version + } +} + +impl> Decodable for NameVer { + fn decode(d: &mut D) -> Result { + let vector: Vec<~str> = try!(Decodable::decode(d)); + Ok(NameVer { name: vector.get(0).clone(), version: semver::parse(vector.get(1).clone()).unwrap() }) + } +} + +impl> Encodable for NameVer { + fn encode(&self, e: &mut S) -> Result<(), E> { + (vec!(self.name.clone(), self.version.to_str())).encode(e) + } +} diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index e51ce77dc..a54663860 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -1,41 +1,6 @@ use std::vec::Vec; use semver; -use semver::{Version,parse}; use core; -use serialize::{Encodable,Encoder,Decodable,Decoder}; - -#[deriving(Clone,Eq,Show,Ord)] -pub struct NameVer { - name: ~str, - version: Version -} - -impl NameVer { - pub fn new(name: &str, version: &str) -> NameVer { - NameVer { name: name.to_owned(), version: semver::parse(version.to_owned()).unwrap() } - } - - pub fn get_name<'a>(&'a self) -> &'a str { - self.name.as_slice() - } - - pub fn get_version<'a>(&'a self) -> &'a Version { - &self.version - } -} - -impl> Decodable for NameVer { - fn decode(d: &mut D) -> Result { - let vector: Vec<~str> = try!(Decodable::decode(d)); - Ok(NameVer { name: vector.get(0).clone(), version: parse(vector.get(1).clone()).unwrap() }) - } -} - -impl> Encodable for NameVer { - fn encode(&self, e: &mut S) -> Result<(), E> { - (vec!(self.name.clone(), self.version.to_str())).encode(e) - } -} /** * Represents a rust library internally to cargo. This will things like where @@ -46,7 +11,7 @@ impl> Encodable for NameVer { */ #[deriving(Clone,Eq,Show)] pub struct Package { - name_ver: NameVer, + name_ver: core::NameVer, deps: Vec, root: ~str, source: ~str, @@ -54,7 +19,7 @@ pub struct Package { } impl Package { - pub fn new(name: &NameVer, deps: &Vec, root: &str, source: &str, target: &str) -> Package { + pub fn new(name: &core::NameVer, deps: &Vec, root: &str, source: &str, target: &str) -> Package { Package { name_ver: name.clone(), deps: deps.clone(), root: root.to_owned(), source: source.to_owned(), target: target.to_owned() } } @@ -62,7 +27,7 @@ impl Package { self.name_ver.get_name() } - pub fn get_version<'a>(&'a self) -> &'a Version { + pub fn get_version<'a>(&'a self) -> &'a semver::Version { self.name_ver.get_version() } diff --git a/src/cargo/core/source.rs b/src/cargo/core/source.rs index e50e08041..a0c49d6e0 100644 --- a/src/cargo/core/source.rs +++ b/src/cargo/core/source.rs @@ -1,5 +1,5 @@ use std::fmt; -use core::package::NameVer; +use core::NameVer; use CargoResult; #[deriving(Clone,Eq)] diff --git a/src/cargo/mod.rs b/src/cargo/mod.rs index 59c284bc8..4c5ace6bb 100644 --- a/src/cargo/mod.rs +++ b/src/cargo/mod.rs @@ -21,9 +21,9 @@ use hammer::{FlagDecoder,FlagConfig,HammerError}; pub mod core; -pub mod util; -pub mod sources; pub mod ops; +pub mod sources; +pub mod util; pub type CargoResult = Result; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 1f1eef4c4..24141931f 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -19,11 +19,9 @@ use std::vec::Vec; use serialize::{Decodable}; use hammer::{FlagDecoder,FlagConfig,FlagConfiguration,HammerError}; use std::io; -use std::os; use std::io::BufReader; use std::io::process::{Process,ProcessExit,ProcessOutput,InheritFd,ProcessConfig}; use {ToCargoError,CargoResult}; -use util::config::{get_config,all_configs}; #[deriving(Decodable)] struct Options { @@ -68,8 +66,6 @@ fn exec_tty(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoRe } fn exec(program: &str, args: &[~str], input: Option<&mut Reader>, configurator: |&mut ProcessConfig|) -> CargoResult { - let paths = get_config(os::getcwd(), "source-paths"); - let mut config = ProcessConfig::new(); config.program = program; config.args = args; diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs index d777eae1e..7223e5a88 100644 --- a/src/cargo/ops/cargo_read_manifest.rs +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -5,8 +5,7 @@ use toml::from_toml; use {CargoResult,ToCargoError,core}; use std::path::Path; use collections::HashMap; -use core::package::NameVer; -use core::dependency::Dependency; +use core::NameVer; #[deriving(Decodable,Encodable,Eq,Clone)] struct SerializedManifest { diff --git a/src/cargo/ops/cargo_rustc.rs b/src/cargo/ops/cargo_rustc.rs index 7a6021fe1..056a47963 100644 --- a/src/cargo/ops/cargo_rustc.rs +++ b/src/cargo/ops/cargo_rustc.rs @@ -5,11 +5,10 @@ use std::io::process::{Process,ProcessConfig,InheritFd}; use std::path::Path; use {CargoResult,CargoError,ToCargoError,NoFlags,core}; -/** - cargo-rustc -- ...args - Delegate ...args to actual rustc command -*/ + +pub fn compile() { +} pub fn execute(_: NoFlags, manifest: core::Manifest) -> CargoResult> { let core::Manifest { root, lib, bin, .. } = manifest; diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index 40ef4f21d..256620bad 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -1,5 +1,5 @@ use core::source::{Source,PackagePath}; -use core::package::NameVer; +use core::NameVer; use CargoResult; use ops::cargo_read_manifest::read_manifest; diff --git a/src/cargo/util/graph.rs b/src/cargo/util/graph.rs new file mode 100644 index 000000000..5e888901f --- /dev/null +++ b/src/cargo/util/graph.rs @@ -0,0 +1,56 @@ +use collections::HashMap; + +trait Node<'a, I: Iterator<&'a Self>> { + fn children(&'a self) -> I; +} + +trait Graph<'a, N: Node<'a, I>, I: Iterator<&'a N>> { + fn nodes(&'a self) -> I; +} + +#[deriving(Clone)] +enum Mark { + InProgress, + Done +} + +/** + * Returns None in the event of a cycle + */ +pub fn topsort<'a, N: Node<'a, I>, G: Graph<'a, N, I>, I: Iterator<&'a N>>(graph: &'a G) -> Option> { + let mut ret = Vec::new(); + let mut iter: I = graph.nodes(); + let mut stack = Vec::<&'a N>::new(); + let mut marks: HashMap<*N, Mark> = HashMap::new(); + + // Prime the stack + for node in iter { + visit(node, &mut ret, &mut marks); + } + + Some(ret) +} + +fn visit<'a, N: Node<'a, I>, I: Iterator<&'a N>>(curr: &'a N, dst: &mut Vec<&'a N>, marks: &mut HashMap<*N, Mark>) { + let ident = curr as *N; + + if marks.contains_key(&ident) { + return; + } + + marks.insert(ident, InProgress); + + let mut iter: I = curr.children(); + + for child in iter { + visit::<'a, N, I>(child, dst, marks); + } + + dst.push(curr); + marks.insert(ident, Done); +} + +#[cfg(test)] +mod test { + // TODO: tests +} diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index 9bd067829..aac3ef546 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -1,4 +1,5 @@ pub use self::process_builder::{process,ProcessBuilder}; +pub mod graph; pub mod process_builder; pub mod config; pub mod important_paths; -- 2.30.2